home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ansi
/
help_7n1.zip
/
CAPTURE.ASM
next >
Wrap
Assembly Source File
|
1987-10-30
|
16KB
|
476 lines
;from VOL7N1.ARC, PC Magazine Jan 88?
;----------------------------------------------------------------------
; CAPTURE is a resident utility which copies an 80x25 screen buffer
; to a file. Activate CAPTURE by pressing ALT-C or any other hot
; key combination defined by the symbols HOTKEY and SHIFT_MASK.
; The filename will be SCREEN.n. The extension begins with .000 and
; is incremented by one each time CAPTURE is activated.
;-----------------------------------------------------------------------
; BIOS_SEG is located in the ROM-BIOS data area
;-----------------------------------------------------------------------
BIOS_SEG SEGMENT AT 0040H
ORG 0017H
KB_FLAG DB ? ;BIOS keyboard shift status
ORG 004AH
CRT_COLS DB ? ;Current number of screen columns
ORG 0050H
CURSOR_POSN DW 8 DUP(?) ;Current cursor location
ORG 0062H
ACTIVE_PAGE DB ? ;Active page for CGA and EGA
BIOS_SEG ENDS
;=======================================================================
CSEG SEGMENT
ASSUME CS:CSEG, DS:CSEG, ES:CSEG
ORG 0100H ;Beginning for .COM programs
START: jmp Initialize ;Initialization code is at end
;-----------------------------------------------------------------------
; Data needed by this program
;-----------------------------------------------------------------------
HOTKEY EQU 2EH ;Scan code for "C" key
SHIFT_MASK EQU 00001000B ;Mask for ALT key held down
COPYRIGHT DB "CAPTURE 1.0 (c) 1987 Ziff Communications Co"
DB 13,10,"Hotkey is ALT-C$",1Ah
PROGRAMMER DB "Tom Kihlken"
INSTALLED_MSG DB 13,10,"Already Installed$"
FILENAME DB "SCREEN.000",0 ;The first filename
OLDINT09 DD ? ;Old hardware keyboard interrupt vector
OLDINT13 DD ? ;Old BIOS disk IO interrupt vector
OLDINT16 DD ? ;Old keyboard input interrupt vector
OLDINT21 DD ? ;Old DOS function interrupt vector
WRIT_FILE DB 0 ;If=1, need to write to disk
ACTIVE DB 0 ;Indicated CAPTURE is in use
DOS_STAT DB 0 ;Current DOS function indicator
BUSY_FLAGS DB 0 ;Bit masked as follows:
; 1 - DOS function is active
; 2 - BIOS disk IO is active
;-----------------------------------------------------------------------
; CAPTURE reads the screen and stores it in an internal buffer.
;-----------------------------------------------------------------------
Capture proc NEAR
ASSUME DS:CSEG, ES:BIOS_SEG
call Get_Curs_Addr ;Cursor addr for this page
PUSH ES:[BX] ;Save the cursor location
mov DI,OFFSET BUFFER ;DS:DI points to the buffer
xor DX,DX ;Start at row 0, column 0
Read_Loop:
cmp DL,CRT_COLS ;Past right edge of screen?
jl Not_Past_Edge ;If screen is less than 80
mov AX,0720H ;columns, then pad with a blank
jmp SHORT Buff_Char
Not_Past_Edge:
call Get_Curs_Addr ;Get address of BIOS cursor
mov ES:[BX],DX ;Tell BIOS where the cursor is
mov BH,ACTIVE_PAGE ;Get active page from BIOS data
mov AH,8 ;BIOS function to read character
int 10H ;Read the character/attribute
Buff_Char:
mov [DI],AX ;Put the character in buffer
inc DI ;Increment the pointer twice
inc DI ;Since we stored a word
inc DL ;Do the next char in same row
cmp DL,80 ;At the right border yet?
jl Read_Loop ;Do 80 characters in this row
inc DH ;Move to next row
xor DL,DL ;Back to left edge (Column 0)
cmp DH,25 ;Done all 25 rows yet?
jl Read_Loop ;Loop until whole screen is read
call Get_Curs_Addr ;Cursor address for this page
POP ES:[BX] ;Recover the cursor position
RET ;Then were finished
Capture ENDP
;-----------------------------------------------------------------------
; This procedure obtains the address of the cursor position for this page
;-----------------------------------------------------------------------
Get_Curs_Addr proc NEAR
ASSUME DS:CSEG, ES:BIOS_SEG
mov BL,ACTIVE_PAGE ;Get the current page number
xor BH,BH ;Convert to a word offset
SHL BX,1 ;Times two for a word
ADD BX,OFFSET CURSOR_POSN ;Add base cursor address
RET
Get_Curs_Addr ENDP
;-----------------------------------------------------------------------
; This copies the buffer contents to a file. It should only be called
; when DOS is in a stable and reentrant condition.
;-----------------------------------------------------------------------
Write_To_File proc NEAR
ASSUME DS:NOTHING, ES:NOTHING
mov WRIT_FILE,0 ;Turn off request flag
STI ;Get interrupts back on
push AX ;Must preserve all registers
push BX
push CX
push DX
push BP
push DS
push ES
push CS
pop DS
ASSUME DS:CSEG ;DS points to out code segment
mov AX,3524H ;Get DOS critical error vector
call DOS_Function ;Do the DOS function
push BX ;Save old INT 24 vector on stack
push ES
; Replace the DOS severe error interrupt with out own routine.
mov DX,OFFSET NewInt24
mov AX,2524H ;Setup to change INT 24h vector
call DOS_Function ;DOS function to change vector
; Try to open the file to determine if it already exists. If it does,
; then just close it and increment the filename.
Open_File: mov DX,OFFSET FILENAME ;DS:DX points to filename
mov AX,3D00H ;Opin file for read access
call DOS_Function ;Do the DOS function
jc Open_Error ;If open error, take jump
mov BX,AX ;Need the handle in BX
mov AH,3EH ;Close this file
call DOS_Function ;Do the DOS function
call Inc_Filename ;Try the next filename
jmp short Open_File
Open_Error:
cmp AX,2 ;Was it file not found error?
jne DOS_Err_Exit ;Exit on any other error
; Now create the file, then write buffer contents and close it.
mov DX,OFFSET FILENAME ;DS:DX points to filename
mov CX,0020H ;Attribute for new file
mov AH,3CH ;Create file for writing
call DOS_Function ;Do the DOS function
jc Close_File ;On any error, take jump
mov BX,AX ;Save handle in BX
mov DX,OFFSET BUFFER ;Point to output buffer
mov CX,4000 ;Write 4000 bytes
mov AH,40H ;DOS write to a device function
call DOS_Function ;Do the DOS function
Close_File:
mov AH,3EH ;DOS function to close the file
call DOS_Function ;Do the DOS function
call Inc_Filename ;Move to next filename
DOS_Err_Exit: pop DS ;Get INT 24H vector from stack
ASSUME DS:NOTHING
pop DX
mov AX,2524H ;Restore critical error vector
call DOS_Function ;Do the DOS function
pop ES ;Finally restore all registers
pop DS
pop BP
pop DX
pop CX
pop BX
pop AX
mov ACTIVE,0 ;CAPTURE is done now
RET ;Finished writing to disk
Write_To_File ENDP
;-----------------------------------------------------------------------
; This routine does a dos function by calling the old interrupt vector
;-----------------------------------------------------------------------
ASSUME DS:NOTHING, ES:NOTHING
DOS_Function proc NEAR
PUSHF ;These instructions simulate
CLI ;an interrupt
call CS:OLDINT21 ;Do the DOS function
STI
RET
DOS_Function ENDP
;-----------------------------------------------------------------------
; This procedure increments the extension for the filename.
;-----------------------------------------------------------------------
Inc_Filename proc NEAR
mov BX,OFFSET FILENAME+9 ;Point to last letter
Inc_Next_Char:
inc BYTE PTR [BX] ;Increment the extension
cmp BYTE PTR [BX],"9" ;Check for carry
jle Inc_Return ;If none, were finished
mov BYTE PTR [BX],"0" ;Set this digit to zero
dec BX ;Backup to next digit
cmp BX,OFFSET FILENAME+6 ;Dont increment the dot
; jle Inc_Return
; jmp short Inc_Next_Char
ja Inc_Next_Char ;TH
Inc_Return:
RET
Inc_Filename ENDP
;-----------------------------------------------------------------------
; Interrupt 09 (Keyboard) Watch for trigger key. When found, ignore
; it and execute the CAPTURE routine.
;-----------------------------------------------------------------------
NewInt09 proc FAR
ASSUME DS:NOTHING, ES:NOTHING
STI ;Allow other interrupts
push AX ;Must save processor state
IN AL,60H ;Get the scan code
cmp AL,HOTKEY ;Is it the hot key?
je Trigger ;If ye